package com.example.tool.utils;

import com.intellij.openapi.diagnostic.Logger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * <p>Title: FileUtil</p>
 * Description: 文件工具
 * <p>CreateTime: 2022/6/25 19:55</p>
 * @author FT
 */
public class FileUtil {
  private static final Logger LOG = Logger.getInstance(FileUtil.class);

  public static void copyFile(String oldPath, String outPath) throws IOException {
    copyFile(new FileInputStream(oldPath), outPath);
  }

  // 将InputStream中的文件拷贝到指定位置
  public static void copyFile(InputStream inputStream, String outPath) throws IOException {
    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outPath));
    int len;
    while ((len = bufferedInputStream.read()) != -1) {
      bufferedOutputStream.write(len);
    }
    byte[] bytes = new byte[1024];
    int size;
    while ((size = bufferedInputStream.read(bytes)) != -1) {
      bufferedOutputStream.write(bytes, 0, size);
    }
    bufferedOutputStream.close();
    bufferedInputStream.close();
  }

  public static boolean isHave(String path) {
    File file = new File(path);
    return !file.exists();
  }

  public static String getXmlBase() {
    return FileUtil.readFile("/demo/base/bean.txt", false);
  }

  public static String getXml(String filePath, boolean isLineFeed) {
    String string = FileUtil.readFile(filePath, isLineFeed);
    if (string != null && isLineFeed) {
      return string.substring(0, string.length() - 1);
    } else {
      return null;
    }
  }

  /**
   * 创建文件所包含的所有层级
   * @param path 文件的绝对路径
   */
  @SuppressWarnings("All")
  public static void createFilePath(String path) {
    File file = new File(path);
    file.mkdirs();
  }

  /**
   * 创建文件并输入指定的内容到文件中
   * @param filePath 文件的绝对路径
   * @param txt      要输入的内容
   */
  @SuppressWarnings("All")
  public static void generateFile(String filePath, String txt) {
    File file = new File(filePath);
    try {
      file.createNewFile();
    } catch (IOException e) {
      e.printStackTrace();
    }
    FileUtil.writeToFile(file, txt);
  }

  /**
   * 生成文件
   * @param filePath     文件生成路径绝对路径
   * @param demoFilePath 文件示例路径相对文件中 示例：/demo/init/DemoPluginInitializer.txt
   * @param function     文件示例中要替换的值操作
   */
  @SuppressWarnings("All")
  public static void generateFile(String filePath, String demoFilePath, Function<String, String> function) {
    String txt = FileUtil.readFile(demoFilePath);
    if (txt != null) {
      String txtReplace = function.apply(txt);
      File file = new File(filePath);
      try {
        String substring = filePath.substring(0, filePath.lastIndexOf("/"));
        if (isHave(substring)) {
          createFilePath(substring);
        }
        file.createNewFile();
      } catch (IOException e) {
        e.printStackTrace();
      }
      FileUtil.writeToFile(file, txtReplace);
    } else {
      LOG.error("SeeyonTool File is not read");
    }
  }

  public static void getAllJar(String basePath, Consumer<String> consumer) {
    boolean tagFirst = true;
    boolean tagSecond = true;
    String pathname = basePath + "/ApacheJetspeed/webapps/seeyon/WEB-INF/lib";
    File baseFile = new File(pathname);
    if (baseFile.exists()) {
      getAllFile(pathname, consumer);
    } else {
      tagFirst = false;
    }

    String str = basePath + "/ApacheJetspeed/lib";
    File strFile = new File(str);
    if (strFile.exists()) {
      getAllFileOn(str, consumer, "jsp-api.jar", "servlet-api.jar");
    } else {
      tagSecond = false;
    }

    if (!tagFirst && !tagSecond) {
      getAllFile(basePath, consumer);
    }
  }

  public static void getAllFileOn(String basePath, Consumer<String> consumer, String... fileName) {
    Arrays.stream(fileName).forEach(str -> consumer.accept(basePath + "/" + str));
  }

  /**
   * 根据传递的绝对路径，来处理该路径下的所有文件，通过Consumer来自定义处理文件规则
   * @param basePath 绝对路径
   * @param consumer 操作方式
   */
  public static void getAllFile(String basePath, Consumer<String> consumer) {
    File baseFile = new File(basePath);
    File[] files = baseFile.listFiles();
    if (files != null) {
      for (File file : files) {
        // 判断是不是文件
        if (file.isDirectory()) {
          getAllFile(file.getAbsolutePath(), consumer);
        } else {
          if (isJar(file)) {
            consumer.accept(file.getAbsolutePath());
          }
        }
      }
    }
  }

  // 获取文件的后缀
  @SuppressWarnings("unused")
  public static String getEndFile(String filePath) {
    return filePath.substring(filePath.lastIndexOf(".") + 1);
  }

  /**
   * 判断文件是不是jar包
   * @param file 对应的文件
   */
  private static boolean isJar(File file) {
    String name = file.getName();
    if (name.lastIndexOf(".") == -1) {
      return false;
    } else {
      return name.substring(name.lastIndexOf(".") + 1).equals("jar");
    }
  }


  public static String readFile(String filePath) {
    return readFile(filePath, true);
  }

  public static String readFile(String filePath, boolean isLineFeed) {
    URL resource = FileUtil.class.getResource(filePath);
    if (resource != null) {
      return readFilePath(resource, isLineFeed);
    } else {
      return null;
    }
  }

  public static String readFilePath(URL resource, boolean isLineFeed) {
    try (InputStream inputStream = resource.openStream();
         InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
         BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
      String line;
      StringBuilder stringBuilder = new StringBuilder();
      while ((line = bufferedReader.readLine()) != null) {
        stringBuilder.append(line);
        if (isLineFeed) {
          stringBuilder.append("\n");
        }
      }
      return stringBuilder.toString();
    } catch (IOException e) {
      return "";
    }
  }

  /**
   * 写数据到文件中
   * @param file  文件
   * @param count 数据
   */
  public static void writeToFile(File file, String count) {
    try (FileOutputStream fileInputStream = new FileOutputStream(file);
         OutputStreamWriter inputStreamReader = new OutputStreamWriter(fileInputStream, StandardCharsets.UTF_8);
         BufferedWriter bufferedWriter = new BufferedWriter(inputStreamReader)) {
      bufferedWriter.write(count);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  public static String upperFirstCase(String str) {
    char[] chars = str.toCharArray();
    if (chars[0] > 91) {
      chars[0] -= 32;
    }
    return String.valueOf(chars);
  }

  public static String lowerFirstCase(String str) {
    char[] chars = str.toCharArray();
    if (chars[0] < 91) {
      chars[0] += 32;
    }
    return String.valueOf(chars);
  }
}
